package com.jeecg.mongo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import com.google.gson.Gson;
import com.jeecg.model.Person;


public class MiniMongo {
	
	/**
	 * 创建数据库
	 * @param dataBaseName
	 */
	public void createDataBase(String dataBaseName,String collectionName){
		String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		String fileName = "mongodb.xml";
		FileOutputStream out = null;
		try {
			out = new FileOutputStream("mongodb_"+dataBaseName+".xml");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		//创建文档
		Document document = new Document();
		//创建根节点元素
		Element root = new Element("database");
		root.setAttribute("name", dataBaseName);
		//创建collecation
		Element collection1 = new Element("collection");
		collection1.setAttribute("name",collectionName);
		Element collection2 = new Element("collection");
		collection2.setAttribute("name","system.indexes");
		Element collection3 = new Element("collection");
		collection3.setAttribute("name","system.users");
		//将collection元素加入根节点之中
		root.addContent(collection1);
		root.addContent(collection2);
		root.addContent(collection3);
		//设置根节点
		document.setRootElement(root);
		//将document写入文件
		XMLOutputter xmlOutputter = new XMLOutputter();
		try {
			xmlOutputter.output(document, out);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
		 try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		}
		
		
	}
	/**
	 * 查询所有记录
	 * @param dataBaseName
	 * @param collectionName
	 * @return
	 */
	public List<Map<String,Object>> queryAllData(String dataBaseName,String collectionName){
		List<Map<String,Object>> ls = new ArrayList<Map<String,Object>>();
		
		try {
			FileInputStream in = new FileInputStream("mongodb_"+dataBaseName+".xml");
			SAXBuilder builder = new SAXBuilder();
			Document document = builder.build(in);
			List<Element> collections = document.getRootElement().getChildren();
			Gson gson = new Gson();
			for(Element collection : collections){
				if(collection.getAttributeValue("name").equals(collectionName)){
					List<Element> docs = collection.getChildren();
					if(docs!=null){
						for(Element doc : docs){							
							if(doc.getText()!=null&&(!doc.getText().equals(""))){
								Map<String,Object> map = gson.fromJson(doc.getText(), Map.class);
								ls.add(map);							
							}
						}
					}
					break;
				}
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(ls.size()>0){
			for(int i=0;i<ls.size();i++){
				System.out.println(ls.get(i).toString());				
			}
		}
		return ls;
	}
	/**
	 * 根据id查询数据
	 * @param dataBaseName
	 * @param collectionName
	 * @param id
	 * @return
	 */
	public Map<String,Object> queryDataById(String dataBaseName,String collectionName,String id){
		Map<String,Object> resultMap = null;
		try {
			FileInputStream in = new FileInputStream("mongodb_"+dataBaseName+".xml");
			SAXBuilder builder = new SAXBuilder();
			Document document = builder.build(in);
			Element root = document.getRootElement();
			List<Element> collections = root.getChildren();
			Gson gson = new Gson();
			for(Element collection : collections){
				if(collection.getAttributeValue("name").equals(collectionName)){
					List<Element> docs = collection.getChildren();
					for(Element doc : docs){
						Map<String,Object> map = gson.fromJson(doc.getText(), Map.class);
						if(map.get("_id").equals(id)){
							System.out.println(map.toString());
							resultMap = map;
							break;
						}
					}
					break;
				}
			}
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return resultMap;
		
	}
	/**
	 * 插入数据
	 * @param dataBaseName
	 * @param collectionName
	 * @param object
	 */
	public void insertData(String dataBaseName,String collectionName,Object object){
		try {
			//获取输入流
			FileInputStream in = new FileInputStream("mongodb_"+dataBaseName+".xml");
			SAXBuilder builder = new SAXBuilder();
			//获取document
			Document document = builder.build(in);
			//获取根节点
			Element root = document.getRootElement();
			List<Element> collections = root.getChildren();
			Gson gson = new Gson();
			for(Element collection : collections){
				if(collection.getAttributeValue("name").equals(collectionName)){
					Map<String,Object> dataMap = new HashMap<String,Object>();
					//生成_id
					String _id = UUID.randomUUID().toString();
					dataMap.put("_id", _id);
					//获取传入对象的Map
					String json = gson.toJson(object);
					Map<String,Object> objectMap = gson.fromJson(json, Map.class);
					//将子map放入带id的map中
					dataMap.putAll(objectMap);
					Element data = new Element("document");
					data.addContent(gson.toJson(dataMap));
					collection.addContent(data);
				}
			}
			XMLOutputter xmlOutputter = new XMLOutputter();
			FileOutputStream out = new FileOutputStream("mongodb_"+dataBaseName+".xml");
			xmlOutputter.output(document, out);
			in.close();
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 修改数据
	 * @param dataBaseName
	 * @param collectionName
	 * @param object
	 */
	public void updateData(String dataBaseName,String collectionName,Object object){
		Gson gson = new Gson();
		Map<String,Object> newMap = gson.fromJson(gson.toJson(object), Map.class);
		if(newMap.get("_id")==null||newMap.get("_id").equals("")){
			System.out.println("修改失败：未包含修改对象的_id");
			return;
		}
		
		try {
			FileInputStream in = new FileInputStream("mongodb_"+dataBaseName+".xml");
			SAXBuilder builder = new SAXBuilder();
			Document document = builder.build(in);
			Element root = document.getRootElement();
			for(Element collection : (List<Element>)root.getChildren()){
				List<Element> documents = collection.getChildren();
				if(collection.getAttributeValue("name").equals(collectionName)){
					if(documents==null){
						return;
					}
					for(Element doc : documents){
						Map<String,Object> oldMap = gson.fromJson(doc.getText(), Map.class);
						if(oldMap==null){
							continue;
						}
						if(oldMap.get("_id").equals(newMap.get("_id"))){
							Set<String> keySet = newMap.keySet();
							for(String key : keySet){
								//若key在原document中存在时，移除原键值对
								if((newMap.get(key)!=null)&&isExistedKey(key,oldMap)){
									oldMap.put(key,newMap.get(key));
								}
								//若key在原document中不存在时，添加至原document中
								if((newMap.get(key)!=null)&&(!isExistedKey(key,oldMap))){
									oldMap.put(key, newMap.get(key));
								}
							}
							doc.removeContent();
							doc.addContent(gson.toJson(oldMap));					
							break;
						}
					}
					break;
				}
				
			}
			FileOutputStream out = new FileOutputStream("mongodb_"+dataBaseName+".xml");
			XMLOutputter xmlOutputter = new XMLOutputter();
			xmlOutputter.output(document, out);
			in.close();
			out.flush();
			out.close();
			System.out.println("修改成功！");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 删除数据
	 * @param dataBaseName
	 * @param collectionName
	 * @param object
	 */
	public void deleteData(String dataBaseName,String collectionName,Object object){
		int count = 0;
		try {
			FileInputStream in = new FileInputStream("mongodb_"+dataBaseName+".xml");
			SAXBuilder builder = new SAXBuilder();
			Document document = builder.build(in);
			Element root = document.getRootElement();
			List<Element> collections = root.getChildren();
			Gson gson = new Gson();
			Map<String,Object> queryMap = gson.fromJson(gson.toJson(object), Map.class);
			for(Element collection : collections){
				if(collection.getAttributeValue("name").equals(collectionName)){
					List<Element> docs = collection.getChildren();
					for(Element doc : docs){
						Map<String,Object> map = gson.fromJson(doc.getText(), Map.class);
						if(map.get("_id").equals(queryMap.get("_id"))){
							collection.removeContent(doc);
							count++;
						}
					}
					break;
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("共删除"+count+"条数据！");
	}
	public boolean isExistedKey(String key,Map<String,Object> map){
		boolean flag = false;
		if(map.size()>0){
			Set<String> keySet = map.keySet();
			for(String ele : keySet){
				if(ele.equals(key)){
					flag = true;
					break;
				}
			}
		}
		return flag;
		
	}
	public static void main(String[] args){
		MiniMongo miniMongo = new MiniMongo();
		//创建数据库
//		miniMongo.createDataBase("foobar", "persons");
		//插入数据
//		Person person1 = new Person("Jack","USA",true,23);
//		miniMongo.insertData("foobar", "persons", person1);
		//修改数据
		Person person2 = new Person();
		person2.set_id("5530243b-ec14-44c7-988a-d532eeabc15f");
//		person2.setName("Tom");
//		miniMongo.updateData("foobar", "persons", person2);
		//查询数据
//		miniMongo.queryAllData("foobar", "persons");
//		miniMongo.queryDataById("foobar", "persons", "34b69bba-0500-4c6e-9fa9-ac74c2c4cbc9");
		miniMongo.deleteData("foobar", "persons",person2);
	}

}
